package com.oro.validator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

public class CodiceFiscaleValidator implements Validator {

	private String regex = "^[A-Za-z]{6}[0-9]{2}[A-Za-z][0-9]{2}[A-Za-z][0-9]{3}[A-Za-z]$";
	private int dispari[] = { 1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20,
			11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23 };
	private Pattern pattern = Pattern.compile(regex);

	private boolean isValid(Object value) {
		if (value == null) {
			return true;
		}
		if (!(value instanceof String)) {
			return false;
		}

		String string = (String) value;
		if (string.length() == 0) {
			return true;
		}

		Matcher m = pattern.matcher(string);

		if (!m.matches()) {
			return false;
		}

		String cf = string.toUpperCase();

		int i = 0, s = 0, c = 0;

		for (i = 1; i <= 13; i += 2) {
			c = cf.charAt(i);
			if (c >= '0' && c <= '9') {
				s = s + c - '0';
			} else {
				s = s + c - 'A';
			}
		}
		for (i = 0; i <= 14; i += 2) {
			c = cf.charAt(i);
			if (c >= '0' && c <= '9') {
				c = c - '0' + 'A';
			}
			s = s + dispari[c - 'A'];
		}

		return s % 26 + 'A' == cf.charAt(15);
	}

	@Override
	public void validate(FacesContext context, UIComponent component,
			Object value) throws ValidatorException {

		if (!isValid(value)) {
			FacesMessage message = new FacesMessage();
			message.setSummary("Codice fiscale non valido.");
			throw new ValidatorException(message);
		}

	}

}
